package com.secure.config;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.secure.advice.RequestBodySecureAdvice;
import com.secure.advice.RequestParameterSecureAdvice;
import com.secure.advice.ResponseSecureAdvice;
import com.secure.context.ApplicationContextHolder;
import com.secure.handler.*;
import com.secure.message.JsonMessageConverter;
import com.secure.properties.SecureProperties;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

/**
 * API安全配置
 *
 * @author duchao
 */
@Slf4j
@Configuration(proxyBeanMethods = false)
@ConditionalOnWebApplication
@EnableConfigurationProperties({SecureProperties.class})
@ConditionalOnProperty(prefix = "api.secure", name = "enable", havingValue = "true")
public class ApiSecureAutoConfiguration {

    /**
     * 加密/解密由服务提供方提供实现
     *
     * @return
     */
    @Bean
    @ConditionalOnMissingBean
    public EncryptDecryptHandler encryptDecryptHandler() {
        return new RsaEncryptDecryptHandler();
    }

    /**
     * 验签由服务消费方提供实现
     *
     * @return
     */
    @Bean
    @ConditionalOnMissingBean
    public SignatureHandler signatureHandler() {
        return new RsaSignatureHandler();
    }

    @Bean
    public SecureRequestHandler secureValidator(ObjectMapper objectMapper, SecureProperties secureProperties, SignatureHandler signatureHandler, EncryptDecryptHandler encryptDecryptHandler) {
        return new SecureRequestHandler(objectMapper, secureProperties, signatureHandler, encryptDecryptHandler);
    }

    @Bean
    public RequestParameterSecureAdvice requestParameterSecureAdvice(ObjectMapper objectMapper, SecureRequestHandler secureRequestHandler) {
        return new RequestParameterSecureAdvice(objectMapper, secureRequestHandler);
    }

    @Bean
    public RequestBodySecureAdvice requestBodySecureAdvice(ObjectMapper objectMapper, SecureRequestHandler secureRequestHandler) {
        return new RequestBodySecureAdvice(objectMapper, secureRequestHandler);
    }

    @Bean
    public ResponseSecureAdvice responseSecureAdvice(SecureProperties secureProperties, EncryptDecryptHandler encryptDecryptHandler) {
        return new ResponseSecureAdvice(secureProperties, encryptDecryptHandler);
    }

    @Bean
    public JsonMessageConverter jsonMessageConverter() {
        return new JsonMessageConverter();
    }

    /**
     * @param requestMappingHandlerMapping 请求映射处理器
     * @return
     */
    @Bean
    public ApplicationListener<ContextRefreshedEvent> applicationListener(RequestMappingHandlerMapping requestMappingHandlerMapping) {
        return event -> {
            ApplicationContextHolder.setApplicationContext(event.getApplicationContext());
            ApplicationContextHolder.setRequestMappingHandlerMapping(requestMappingHandlerMapping);
        };
    }
}

